//5.object
//object和Object
    // let a : object      //a能存储的数据类型是【非原始类型】数据类型
    // let b : Object      //b能存储的数据类型是可以调用Object方法的数据类型，比如toString();除了null和undefined

//声明对象类型
    //定义对象字面量类型字面量来限制对象
    // let person : {name:string,age?:number}

    // person = {name:'张三'}

//索引签名
// let person1 : {
//     name:string
//     age?:number
//     [key:string]:any        //不一定是key，随意任何都可以
// }

//     person1 = {name:'张三',age:18,city:'北京'}

//声明函数类型
// let count: (a:number,b:number)=> number     //a,b是传入的两个类型为number的参数，返回值为number

// count = function(x,y){
//     return x+y
// }
//声明数组类型
// let arr1: string[] = ['a','b']
// let arr2: Array<number>
// arr2 = [123,45]

// let arr1 : [string,number,number?]
// let arr2 : [number,...string[]]     //第一个元素使number类型，后面的元素使任意数量的string类型

// arr1 = ['a',1]
// arr2 = [123,'a','s']


const enum Direction {
    Up,     //0
    Down,   //1
    Left,   //2
    Right   //3
}

// console.log(Direction.Up)       //结果为0
// console.log(Direction[0])       //结果为'Up'

// function walk(data:Direction){
//     if(data === Direction.Up){
//         console.log("向【上】走")
//     }
//     else if(data === Direction.Down){
//         console.log("向【下】走")
//     }
//     else if(data === Direction.Left){
//         console.log("向【左】走")
//     }
//     else if(data === Direction.Right){
//         console.log("向【右】走")
//     }
// }

// walk(Direction.Up)

// enum Direction {
//     Up = 'up',     
//     Down = 'down',   
//     Left = 'left',   
//     Right = 'right'  
// }

// //联合类型
// type Status = number | string
// const s1:Status = 1
// const s2:Status = '1'

// //交叉类型
// type Area = {
//     width : number
//     height : number
// }

// type Address = {
//     num : number
//     cell : number
//     room : string
// }

// type House = Area&Address

// const house:House ={
//     height:100,
//     width:100,
//     num : 2,
//     cell : 1,
//     room : '302'
// }

// function demo():void{
//     //只有返回undefined和不返回才合法
//     return undefined
// }

// type func = ()=>void
// const f1:func = function(){
//     return 100
// }

// class Person {
//     name :string
//     age:number
//     constructor(name :string,age:number){
//         this.age = age
//         this.name = name
//     }
//     speak(){
//         console.log(`我叫：${this.name}，今年${this.age}岁`)
//     }
// }

// class Student extends Person {
//     grade:string
//     constructor(name :string,age:number,grade:string){
//         super(name,age)
//         this.grade = grade
//     }
//     override speak(){       //重写speak
//         console.log(`我是学生，我叫：${this.name}，今年${this.age}岁`)
//     }
// }

// class Person {
//     constructor(public name :string,public age:number){
//     }
// }
// abstract class Package{
//     //构造方法
//     constructor(public weight:number){}
//     //抽象方法
//     abstract calculate():number
//     //具体方法
//     printPackage(){
//         console.log(`包裹重量为：${this.weight}，运费为：${this.calculate()}`)
//     }
// }

// class StandardPackage extends Package {
//     constructor(weight:number,public unitPrice:number){
//         super(weight)
//     }
//     calculate(): number {
//         return this.unitPrice*this.weight
//     }
// }

// const s1 = new StandardPackage(10,5)
// s1.printPackage()

// interface PersonInterface {
//     name:string
//     age:number
//     speak(n:number):void
// }

// class Person implements PersonInterface {
//     constructor(
//         public name:string,
//         public age:number       
//     ){}
//     speak(n: number): void {
//         for (let i = 0; i < n; i++) {
//             console.log('名字是${this.name}，年龄是${this.age}')
//         }
//     }
// }

// const p1 = new Person('zhangsan',18)
// p1.speak(5)

// interface UserInterface {
//     name:string
//     readonly gender:string
//     age?:number
//     run:(n:number)=>void
// }

// const user : UserInterface = {      //当做类型用
//     name:'zhangsan',
//     gender:'男',
//     run(n){
//         console.log(`跑了${n}米`)
//     }
// }

// interface CountInterface {
//     (a:number,b:number):number
// }

// const count:CountInterface = (x,y) => {
//     return x+y
// }

// interface PersonInterface {
//     name:string
//     age:number
// }

// interface StudentInterface extends PersonInterface {
//     grade:string
// }

// const stu:StudentInterface = {
//     name:'zhangsan',
//     age:18,
//     grade:'高三'
// }

// interface PersonInterface {
//     name:string
//     age:number
// }

// interface PersonInterface {
//     grade:string
// }

// const person:PersonInterface = {
//     name:'zhangsan',
//     age:18,
//     grade:'高三'
// }
// interface FlyInterface {
//     swim():void
// }

// interface FlyInterface {
//     fly():void
// }

// class Duck implements FlyInterface,FlyInterface {
//     fly(){}
//     swim(){}
// }

// function LogData<T>(data:T){
//     console.log(data)
// }

// LogData<number>(100)
// LogData<string>('1')

// function LogData<T,U>(data1:T,data2:U):T|U{
//     console.log(data1,data2)
//     return Date.now() % 2 ? data1 : data2
// }

// LogData<number,string>(100,'100')
// LogData<string,number>('1',100)

// interface Person<T>{
//     name:string
//     age:number
//     extraInfo:T
// }

// let p1:Person<number> = {
//     name:'zhangsan',
//     age:18,
//     extraInfo:666
// }

class Person<T>{
    constructor(
        public name :string,
        public age:number,
        public extraInfo:T,
        ){ }
}

let p1 = new Person<number>('zhangsan',18,666)